﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Video.DirectShow;
using AForge.Controls;
using LogLib;
using System.IO.MemoryMappedFiles;
using System.Threading;
using System.IO;
using ComLib.ConfigService;
using MetroFramework;
using System.Drawing.Imaging;
using System.Media;
using System.Diagnostics;
using ComLib.ComType;
using NewCapturerDemo.Config;
using System.Reflection;
using System.Threading.Tasks;
using PipeClient;

namespace NewCapturerDemo
{
    public partial class FormCapturer : Form
    {
        #region 专用于异步发送启动消息
        protected IntPtr ParentFormHandle = IntPtr.Zero;
        /// <summary>
        /// 指示是否已经通知主窗体加载完成
        /// </summary>
        protected bool _bNotified = false;
        public string AppName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
        #endregion

        protected SoundPlayer _player = new SoundPlayer();

        private VideoCaptureDevice _device = null;

        private Byte[] Data = null;

        public static long MemoryCapacity = 50000000;

        public long nReadDataLength = 0;

        /// <summary>
        /// 实时取景状态是不是处于打开状态
        /// </summary>
        private bool _isPlayerOn = false;
        public bool OnLiving
        {
            get { return _isPlayerOn; }
        }

        /// <summary>
        /// 指示在拍照后是否显示照片预览
        /// </summary>
        private bool _showTakenPhoto = false;
        public bool ShowTakenPhoto
        {
            get { return _showTakenPhoto; }
        }

        /// <summary>
        /// 显示拍照特效
        /// </summary>
        private bool _displayEffects = false;
        public bool DisplayEffects
        {
            get { return _displayEffects; }
        }

        private List<KeyValuePair<string, string>> listDevices = new List<KeyValuePair<string, string>>();

        public Camera _camera = new Camera();

        private CameraOption _option = new CameraOption();
        public CameraOption Option
        {
            get { return _option; }
        }

        /// <summary>
        /// 控制拍照窗口的句柄
        /// </summary>
        protected IntPtr ControllerHandle = IntPtr.Zero;

        private const string shareName = "AforgeNewVideoFrame";

        private const string mutexName = "MemoryMapMutex";

        /// <summary>
        /// 相机参数设置对话框
        /// </summary>
        private FormCameraSetting formConfig;

        public FormCapturer(CameraOption option)
        {
            _option = option;
            //LoadConfig();
            InitializeComponent();
            InitCtrls();
        }

        public FormCapturer(CameraOption option, string arg)
        {
            _option = option;
            //LoadConfig();
            if (!string.IsNullOrEmpty(arg))
            {
                ParentFormHandle = (IntPtr)Int32.Parse(arg);
            }
            InitializeComponent();
            InitCtrls();
        }

        private void InitCtrls()
        {
            SetCustomStyles();
            SetMenuItemsEnabled(_isPlayerOn);
            InitVideoSourcePlayer();
            InitPictureBoxGif();
            if (ParentFormHandle != IntPtr.Zero)
            {
                this.Location = new Point(2000, 2000);
            }
            else
            {
                this.Location = new Point(339, 39);
            }
        }

        private void SetCustomStyles()
        {
            this.SetStyle(ControlStyles.UserPaint
              | ControlStyles.AllPaintingInWmPaint
              | ControlStyles.OptimizedDoubleBuffer
              | ControlStyles.ResizeRedraw,
              true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.Opaque, false);
            this.UpdateStyles();
        }

        private void InitVideoSourcePlayer()
        {
            Size size = _option.VideoPlayerSize;
            this.Size = size;
            videoSourcePlayer1.Parent = panel1;
            videoSourcePlayer1.Size = new Size(size.Width - 2, size.Height - 2);
            videoSourcePlayer1.Location = new Point(0, 0);
            videoSourcePlayer1.RotateFlipValue = _camera.Option.RotateFlipValue;
            ResetAdjustButtons();
            ShowManualAdjustControls(false);
        }

        private List<Control> listAdjustCtls = new List<Control>();
        private void InitAdjustCtls()
        {
            listAdjustCtls.Add(buttonAddBrightness);
            listAdjustCtls.Add(buttonReduceBrightness);
            listAdjustCtls.Add(buttonAddExposure);
            listAdjustCtls.Add(buttonReduceExposure);

            listAdjustCtls.Add(labelExposure);
            listAdjustCtls.Add(labelExposureVal);
            listAdjustCtls.Add(labelBrightness);
            listAdjustCtls.Add(labelBrightnessVal);
        }

        /// <summary>
        /// 指示预览界面是否显示手动调节控件
        /// </summary>
        private void ShowManualAdjustControls(bool visable)
        {
            for (int i = 0; i < listAdjustCtls.Count; i++)
            {
                listAdjustCtls[i].Visible = visable && _camera.Option.EnableAdjustParams;
            }
            if (_camera.Option.EnableAdjustParams)
            {              
                if (visable && _camera != null)
                {
                    CamProperties properties = _camera.Properties;
                    labelBrightnessVal.Text = properties[CamProc.Brightness].Value.ToString();
                    labelExposureVal.Text = properties[CamProc.Exposure].Value.ToString();
                }
            }                           
        }

        /// <summary>
        /// 调整界面人工参数调节按钮的位置
        /// </summary>
        private void ResetAdjustButtons()
        {
            buttonAddBrightness.Parent = videoSourcePlayer1;
            buttonReduceBrightness.Parent = videoSourcePlayer1;
            buttonAddExposure.Parent = videoSourcePlayer1;
            buttonReduceExposure.Parent = videoSourcePlayer1;
            labelExposure.Parent = videoSourcePlayer1;
            labelExposureVal.Parent = videoSourcePlayer1;
            labelBrightness.Parent = videoSourcePlayer1;          
            labelBrightnessVal.Parent = videoSourcePlayer1;
          
            Size playSize = videoSourcePlayer1.Size;
            Size btnSize = buttonAddBrightness.Size;

            int leftBtnBrightness = 6;
            int leftExporsure = playSize.Width - btnSize.Width - 6;

            int leftBrightnessVal = 6;

            int leftLabelExp = playSize.Width - labelExposure.Width - 6;
            //int leftExposureVal = playSize.Width - labelExposureVal.Width - 6; ;

            int topAdd = playSize.Height / 4 - btnSize.Height/2;
            int topReduce = playSize.Height/4*3 - btnSize.Height / 2;
          
            int titleTop = playSize.Height / 2 - labelBrightness.Height-2;
            int valTop = playSize.Height / 2 + 2;

            buttonAddBrightness.Location = new Point(leftBtnBrightness, topAdd);
            buttonReduceBrightness.Location = new Point(leftBtnBrightness, topReduce);
            buttonAddExposure.Location = new Point(leftExporsure, topAdd);
            buttonReduceExposure.Location = new Point(leftExporsure, topReduce);

            labelBrightness.Location = new Point(leftBrightnessVal, titleTop);
            labelBrightnessVal.Location = new Point(leftBrightnessVal, valTop);

            labelExposure.Location = new Point(leftLabelExp, titleTop);          
            labelExposureVal.Location = new Point(leftLabelExp, valTop);       
        }

        private void FormCapturer_Load(object sender, EventArgs e)
        {
            try
            {
                InitAdjustCtls();
                ShowManualAdjustControls(false);
                if (InitCamera())
                {
                    OnAppStartupFinished();
                }
                else
                {
                    OnAppStartupFinished(0, _camera.ErrorMessage);
                    if (ParentFormHandle == IntPtr.Zero)
                    {
                        MessageBox.Show(_camera.ErrorMessage);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.WriteException(ex.ToString());
                OnAppStartupFinished(0, ex.Message);
            }
        }

        public void OnPhotoTaken(Bitmap source)
        {
            if (this.InvokeRequired)
            {
                Action<Bitmap> outdelegate = new Action<Bitmap>(OnPhotoTaken);
                this.Invoke(outdelegate, new object[] { source });
                return;
            }
            
            // 进入拍照显示状态，暂停视频流更新和人脸检测
            if (_displayEffects)
            {
                videoSourcePlayer1.Visible = false;          
                ShowPhotoTakenEffects(source); 
                videoSourcePlayer1.Visible = true;
            }       
            SendCommand(CustomWindowsMessage.MSG_CAP_PHOTO_OK);          
            takePhotoToolStripMenuItem.Enabled = true;
        }

        public void OnShottingCompleted()
        {
            videoSourcePlayer1.Visible = false;
        }

        private void StartCapturer()
        {
            if (!_camera.PickTheCapture())
            {
                MessageBox.Show(_camera.ErrorMessage);
                return;
            }
            StartVideoPlayer();
        }

        private void StopCapturer()
        {
            StopVideoPlayer();
        }

        public static Bitmap BytesToBitmap(byte[] Bytes)
        {
            MemoryStream stream = null;
            try
            {
                stream = new MemoryStream(Bytes);
                return new Bitmap(new Bitmap(stream));
            }
            catch (ArgumentNullException ex)
            {
                throw ex;
            }
            catch (ArgumentException ex)
            {
                throw ex;
            }
            finally
            {
                stream.Close(); 
                stream.Dispose();
                stream = null;
            }
        }

        private void TakeImageFormShareMemory()
        {
            if (this.InvokeRequired)
            {
                Action handler = new Action(TakeImageFormShareMemory);
                this.BeginInvoke(handler, new object[] { });
                return;
            }
            Bitmap bmp = BytesToBitmap(Data);
            OnPhotoTaken(bmp);
            if (_showTakenPhoto)
            {
                FormPhotoPreviewing form = new FormPhotoPreviewing(bmp);
                form.ShowDialog();
            }
            bmp.Dispose();
            bmp = null;
        }

        private void OnPhotoDataWrittenInShareMemory(object sender, EventArgs e)
        {
            Mutex mutex = Mutex.OpenExisting(mutexName);
            if (!mutex.WaitOne(1000))
            {
                MessageBox.Show("等待处理共享数据超时!");
                return;
            }
            using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting(shareName))
            {
                //注意这里的偏移量
                using (MemoryMappedViewStream stream = mmf.CreateViewStream(0, 8))
                {
                    var reader = new BinaryReader(stream);
                    nReadDataLength = reader.ReadInt64();
                }

                //注意这里的偏移量
                using (MemoryMappedViewStream stream = mmf.CreateViewStream(8, 0))
                {
                    var reader = new BinaryReader(stream);
                    Data = new Byte[nReadDataLength];
                    reader.Read(Data, 0, (int)nReadDataLength);
                }              
            }
            mutex.ReleaseMutex();
            TakeImageFormShareMemory();
        }

        /// <summary>
        /// 执行拍照命令，激活拍照开关
        /// </summary>
        /// <param name="showing">指示是否显示拍照结果，默认否</param>
        /// <param name="displayEffect">指示是否显示拍照特效，默认否</param>
        private void TakePhoto(bool showing = false, bool displayEffect = false)
        {
            _showTakenPhoto = showing;
            _displayEffects = displayEffect;
            if (_device != null)
            {
                _device.NeedWriteToMemoryMappedFile = true;
            }
        }

        public bool InitCamera()
        {
            listDevices = Camera.GetAllDevices();          
            if (!_camera.Connected())
            {
                return false;          
            }
            if (!_camera.PickTheCapture())
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 启动播放器
        /// </summary>
        public void StartVideoPlayer()
        {
            _device = _camera.Capture;
            _device.WrittenInMemoryMappedFile += OnPhotoDataWrittenInShareMemory;
            videoSourcePlayer1.VideoSource = _camera.Capture;
            videoSourcePlayer1.PlayingAborted += OnPlayerAborted;
            videoSourcePlayer1.Start();
            _isPlayerOn = true;
            SetMenuItemsEnabled(_isPlayerOn);

            ShowManualAdjustControls(true);
            Log.WriteAsync("镜头已打开，播放器已启动...");
            SendCommand(CustomWindowsMessage.MSG_CAP_START_OK);                          
        }

        /// <summary>
        /// 重新启动播放器
        /// </summary>
        public bool RestartVideoPlayer()
        {
            if (_camera.PickTheCapture())
            {
                StartVideoPlayer();
                return true;
            }
            return false;
        }

        private void OnPlayerAborted(object sender, string reason)
        {
            if (this.InvokeRequired)
            {
                VideoSourcePlayer.PlayingAbortedEventHandler outdelegate
                    = new VideoSourcePlayer.PlayingAbortedEventHandler(OnPlayerAborted);
                this.BeginInvoke(outdelegate, new object[] { sender, reason });
                return;
            }
            Log.WriteAsync(string.Format("检测到镜头发生了错误, 原因:{0}", reason));
            SendCommand(CustomWindowsMessage.MSG_CAP_ERROR, reason);
        }

        /// <summary>
        ///  Stop play
        /// </summary>
        public void StopVideoPlayer()
        {
            if (!_isPlayerOn)
            {
                return;
            }
            try
            {
                if (_camera != null)
                {
                    if (videoSourcePlayer1.VideoSource != null)
                    {
                        // stop video device
                        videoSourcePlayer1.PlayingAborted -= OnPlayerAborted;
                        videoSourcePlayer1.SignalToStop();
                        videoSourcePlayer1.WaitForStop();
                        videoSourcePlayer1.VideoSource = null;
                        _camera.CapturePicked = false;
                        _device.WrittenInMemoryMappedFile -= OnPhotoDataWrittenInShareMemory;
                        _device = null;
                        _isPlayerOn = false;
                        SetMenuItemsEnabled(_isPlayerOn);
                        ShowManualAdjustControls(false);
                    }
                    Log.WriteAsync("镜头已经关闭，播放器已经停止运行...");
                    SendCommand(CustomWindowsMessage.MSG_CAP_STOP_OK);
                }
            }
            catch (Exception ex)
            {
                Log.WriteExceptionAsync(ex.ToString());
            }            
        }

        private void SetMenuItemsEnabled(bool playing)
        {
            启动预览ToolStripMenuItem.Enabled = !playing;
            stopViewToolStripMenuItem.Enabled = playing;
            takePhotoToolStripMenuItem.Enabled = playing;
            cameraSettingToolStripMenuItem.Enabled = playing;
            takingOptionToolStripMenuItem.Enabled = !playing;
            exitToolStripMenuItem.Enabled = !playing;
            DefalutSettingToolStripMenuItem.Enabled = playing;
            //aboutToolStripMenuItem.Enabled = true;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
          
        }
   
        private void InitPictureBoxGif()
        {
            pictureBoxGif.Size = panel1.Size;
            pictureBoxGif.Parent = panel1;
            pictureBoxGif.Location = new Point(0, 0);
            pictureBoxGif.Visible = false;
        }

        private void CloseAllOtherForm()
        {
            if (AutoMetroMessageBox.isOnShowing)
            {
                AutoMetroMessageBox.Close(false);
            }
            if (formConfig != null && !formConfig.IsDisposed)
            {
                formConfig.Close();
                formConfig.Dispose();
                formConfig = null;
            }
        }

        public void CloseAutoMessageBox()
        {
            if (AutoMetroMessageBox.isOnShowing)
            {
                AutoMetroMessageBox.Close(false);
            }
        }

        private void OpenProcessSettings()
        {
            if ((formConfig != null
                && !formConfig.IsDisposed)
                || _camera == null)
            {
                return;
            }
            try
            {
                if (formConfig == null)
                {
                    formConfig = new FormCameraSetting(_camera);
                    formConfig.CamPropertyUpdated += OnCameraPropertyUpdated;
                    if (formConfig.ShowDialog() == DialogResult.OK)
                    {                       
                        ShowManualAdjustControls(buttonAddBrightness.Visible);
                    }
                    formConfig.CamPropertyUpdated -= OnCameraPropertyUpdated;
                    formConfig.Dispose();
                    formConfig = null;
                }
            }
            catch (Exception ex)
            {
                Log.WriteException("捕获异常:" + ex.ToString());
            }
        }

        /// <summary>
        /// 显示拍照特效
        /// </summary>
        /// <param name="MyBitmap"></param>
        private void ShowPhotoTakenEffects(Bitmap img)
        {
            Bitmap transImage = AForge.Imaging.Image.Clone(img);
            transImage.RotateFlip(RotateFlipType.RotateNoneFlipX);
            pictureBoxGif.Visible = true;
            try
            {
                // 播放特效声音
                _player.Play();
                // 显示图形特效
                // 变黑再变亮显示图像
                using (Graphics g = this.pictureBoxGif.CreateGraphics())
                {
                    g.Clear(Color.Black);
                    int width = transImage.Width;
                    int height = transImage.Height;
                    int w =  _option.VideoPlayerSize.Width;
                    int h = _option.VideoPlayerSize.Height;
                    int x = (pictureBoxGif.Width - w) / 2;
                    int y = (pictureBoxGif.Height - h) / 2;
                    Rectangle showRec = new Rectangle(x, y, w, h);
                    ImageAttributes attributes = new ImageAttributes();
                    ColorMatrix matrix = new ColorMatrix();
                    //创建淡出颜色矩阵
                    matrix.Matrix00 = (float)0.0;
                    matrix.Matrix01 = (float)0.0;
                    matrix.Matrix02 = (float)0.0;
                    matrix.Matrix03 = (float)0.0;
                    matrix.Matrix04 = (float)0.0;
                    matrix.Matrix10 = (float)0.0;
                    matrix.Matrix11 = (float)0.0;
                    matrix.Matrix12 = (float)0.0;
                    matrix.Matrix13 = (float)0.0;
                    matrix.Matrix14 = (float)0.0;
                    matrix.Matrix20 = (float)0.0;
                    matrix.Matrix21 = (float)0.0;
                    matrix.Matrix22 = (float)0.0;
                    matrix.Matrix23 = (float)0.0;
                    matrix.Matrix24 = (float)0.0;
                    matrix.Matrix30 = (float)0.0;
                    matrix.Matrix31 = (float)0.0;
                    matrix.Matrix32 = (float)0.0;
                    matrix.Matrix33 = (float)0.0;
                    matrix.Matrix34 = (float)0.0;
                    matrix.Matrix40 = (float)0.0;
                    matrix.Matrix41 = (float)0.0;
                    matrix.Matrix42 = (float)0.0;
                    matrix.Matrix43 = (float)0.0;
                    matrix.Matrix44 = (float)0.0;
                    matrix.Matrix33 = (float)1.0;
                    matrix.Matrix44 = (float)1.0;
                    //从1到0进行修改色彩变换矩阵主对角线上的数值
                    //依次减少每种色彩分量                 
                    Single count = (float)1.0;
                    while (count > 0.0)
                    {
                        matrix.Matrix00 = (float)count;
                        matrix.Matrix11 = (float)count;
                        matrix.Matrix22 = (float)count;
                        matrix.Matrix33 = (float)count;
                        attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                        g.DrawImage(transImage, showRec, 0, 0, width, height, GraphicsUnit.Pixel, attributes);
                        System.Threading.Thread.Sleep(4);
                        count = (float)(count - 0.25);
                    }
                    //从0到1进行修改色彩变换矩阵主对角线上的数值
                    //使三种基准色的饱和度渐增
                    g.Clear(Color.Black);
                    System.Threading.Thread.Sleep(100);
                    count = (float)0.0;
                    while (count < 1.0)
                    {
                        matrix.Matrix00 = count;
                        matrix.Matrix11 = count;
                        matrix.Matrix22 = count;
                        matrix.Matrix33 = count;
                        attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                        g.DrawImage(transImage, showRec, 0, 0, width, height, GraphicsUnit.Pixel, attributes);
                        System.Threading.Thread.Sleep(2);
                        count = (float)(count + 0.5);
                    }
                }
                transImage.Dispose();
                transImage = null;
                pictureBoxGif.Visible = false;
            }
            catch (Exception ex)
            {
                Log.WriteException("捕获异常:" + ex.ToString());
            }
        }

        /// <summary>
        /// 连续点击激活次数统计
        /// </summary>
        private int active_click_count = 0;

        private Stopwatch sw_click = new Stopwatch();

        private void OnEnterCamSettingSection()
        {
            // 工作页面不允许呼出菜单
            if ((formConfig != null && !formConfig.IsDisposed) 
                || _camera == null
                || !_isPlayerOn)
            {
                return;
            }
            if (sw_click.IsRunning)
            {
                if (sw_click.ElapsedMilliseconds > 2000)
                {
                    sw_click.Reset();
                    active_click_count = 0;
                }
                else
                {
                    active_click_count++;
                }
                if (active_click_count == 3)
                {
                    sw_click.Reset();
                    active_click_count = 0;
                    OpenProcessSettings();
                }
            }
            else
            {
                sw_click.Restart();
            }
        }

        private void videoSourcePlayer1_Click(object sender, EventArgs e)
        {
            OnEnterCamSettingSection();
        }

        private void pictureBoxGif_Click(object sender, EventArgs e)
        {
            OnEnterCamSettingSection();
        }

        /// <summary>
        /// 处理来自其他进程发来的消息
        /// </summary>
        /// <param name="m"></param>
        private void OnCustomMsgReceived(System.Windows.Forms.Message m)
        {
            try
            {
                COPYDATASTRUCT cdStruct = new COPYDATASTRUCT();
                Type mytype = cdStruct.GetType();
                cdStruct = (COPYDATASTRUCT)m.GetLParam(mytype);
                ControllerHandle = cdStruct.dwData;
                int id = (int)m.WParam;
                switch (id)
                {
                    case CustomWindowsMessage.MSG_CAP_SETTING:
                        {
                            Log.WriteAsync("收到消息，打开参数设置.");
                            OpenProcessSettings();
                        }
                        break;
                    case CustomWindowsMessage.MSG_CAP_SETTING_DEFAULT: // 设置相机本地保存的默认参数
                        {
                            Log.WriteAsync("收到消息，启用默认参数设置.");
                            if(_camera != null && _isPlayerOn)
                            {
                                _camera.InitProperties();
                                ShowManualAdjustControls(buttonAddBrightness.Visible);
                            }
                        }
                        break;
                    case CustomWindowsMessage.MSG_CAP_DO:
                        {
                            Log.WriteAsync("收到消息，执行拍照.");
                            TakePhoto();
                        }
                        break;
                    case CustomWindowsMessage.MSG_CAP_DOFORMAL:
                        {
                            Log.WriteAsync("收到消息，执行正式拍照.");
                            TakePhoto(false, true);
                        }
                        break;
                    case CustomWindowsMessage.MSG_CAP_START:
                        {
                            Log.WriteAsync("收到消息，开始启动镜头预览.");
                            StartCapturer();
                        }
                        break;
                    case CustomWindowsMessage.MSG_CAP_STOP:
                        {
                            Log.WriteAsync("收到消息，停止镜头预览.");
                            StopCapturer();
                        }
                        break;
                    default:
                        break;
                }
            }
            catch (Exception e)
            {
                Log.WriteException(e.ToString());
            }           
        }

        /// <summary>
        /// 通知当前模块回到应用程序主页
        /// </summary>
        private void SendCommand(int command, string message = "Command")
        {
            int uMsg = WindowsMessage.WM_COPYDATA;
            int wParam = command;
            string strMsgText = message;
            int nLen = Encoding.Unicode.GetBytes(strMsgText).Length;
            COPYDATASTRUCT dataStr = new COPYDATASTRUCT();
            dataStr.dwData = (IntPtr)uMsg;
            dataStr.cbData = nLen;
            dataStr.lpData = strMsgText;
            WindowsAPI.SendMessage(ControllerHandle, uMsg, wParam, ref dataStr);
        }    

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            switch (m.Msg)
            {
                case WindowsMessage.WM_COPYDATA:
                    OnCustomMsgReceived(m);
                    break;
                case WindowsMessage.WM_CLOSE:
                    StopCapturer();
                    break;
                default:
                    break;
            }
            base.WndProc(ref m);
        }

        private void 启动预览ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Log.WriteAsync("收到右键启动预览消息，开始启动镜头预览.");
            StartCapturer();
        }

        private void stopViewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Log.WriteAsync("收到右键消息，停止镜头预览.");
            StopCapturer();
        }

        private void takePhotoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            takePhotoToolStripMenuItem.Enabled = false;
            Log.WriteAsync("收到右键消息，执行拍照.");
            TakePhoto(true, true);
        }

        private void SetAsDefalutSettingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            _camera.InitProperties();
            ShowManualAdjustControls(buttonAddBrightness.Visible);
        }

        private void cameraSettingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Log.WriteAsync("收到右键消息，打开镜头参数设置.");
            OpenProcessSettings();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormAbout form = new FormAbout();
            form.ShowDialog();
        }

        private void takingOptionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Log.WriteAsync("打开了拍照和预览选项设置");
            FormConfig form = new FormConfig();
            if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                AutoMetroMessageBox.Show(this, 
                    "参数设置成功!", 
                    "温馨提示",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information,
                    6);
                InitVideoSourcePlayer();
                _camera.LoadConfig();
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// 通知主窗体该进程启动已经完成
        /// </summary>
        protected void OnAppStartupFinished(int code = 1, string msg = "程序加载成功")
        {
            // 当父窗体为空时，不需要通知
            if (IntPtr.Zero == ParentFormHandle || _bNotified)
            {
                Log.WriteAsync(string.Format("{0}获取父进程主窗口句柄为空，不启用进程监测.", AppName));
                return;
            }
            string sendMsg = string.Format("{0}#{1}#{2}", AppName, code, msg);
            Pipe t = new Pipe(2, sendMsg, "MainStartup");
            Task.Factory.StartNew(new Action(t.run));
            Log.WriteAsync("已经通知主窗体启动完成: " + AppName);
            _bNotified = true;
        }

        private void SetPlayerSize(Size size)
        {               
            int iScreenWidth = Screen.PrimaryScreen.Bounds.Width;
            int iScreenHeight = Screen.PrimaryScreen.Bounds.Height;
            this.Size = size;
            if (size.Height <= iScreenHeight)
            {
                int x = (iScreenWidth - size.Width) / 2;
                int y = (iScreenHeight - size.Height) / 2;
                this.Location = new Point(x, y);
            }
            else
            {
                this.Location = new Point(0, 0);
            }
            videoSourcePlayer1.Parent = panel1;
            videoSourcePlayer1.Size = new Size(size.Width - 2, size.Height - 2);
            videoSourcePlayer1.Location = new Point(0, 0);
            InitPictureBoxGif();
            ResetAdjustButtons();
        }

        private void toolStripMenuItemSize300_Click(object sender, EventArgs e)
        {
            SetPlayerSize(new Size(250, 300));
        }

        private void toolStripMenuItemSize360_Click(object sender, EventArgs e)
        {
            SetPlayerSize(new Size(300, 360));
        }

        private void toolStripMenuItemSize600_Click(object sender, EventArgs e)
        {
            SetPlayerSize(new Size(500, 600));
        }

        private void toolStripMenuItemSize720_Click(object sender, EventArgs e)
        {
            SetPlayerSize(new Size(600, 720));
        }

        private void toolStripMenuItemSize1080_Click(object sender, EventArgs e)
        {
            SetPlayerSize(new Size(900, 1080));
        }

        private void toolStripMenuItemSize1440_Click(object sender, EventArgs e)
        {
            SetPlayerSize(new Size(1200, 1440));
        }

        private void control_MouseDown(object sender, MouseEventArgs e)
        {
            if (ParentFormHandle != IntPtr.Zero)
            {
                return;
            }
            mouse_offset = new Point(-e.X, -e.Y);
        }

        private Point mouse_offset;

        private void videoSourcePlayer1_MouseMove(object sender, MouseEventArgs e)
        {
            if (ParentFormHandle != IntPtr.Zero)
            {
                return;
            }
            if (e.Button == MouseButtons.Left)
            {
                Point mousePos = Control.MousePosition;
                mousePos.Offset(mouse_offset.X, mouse_offset.Y);
                Location = mousePos;
            }
        }

        private void videoSourcePlayer1_SizeChanged(object sender, EventArgs e)
        {

        }

        private void buttonAddBrightness_Click(object sender, EventArgs e)
        {
            CamProperties Properties = _camera.Properties;
            PropPair range = Properties[CamProc.Brightness];
            double currentVal = _camera.GetBrightness();
            if(currentVal+1<=range.Max)
            {
                _camera.SetBrightness(currentVal + 1);
                labelBrightnessVal.Text = _camera.GetBrightness().ToString();
            }           
        }

        private void buttonReduceBrightness_Click(object sender, EventArgs e)
        {
            CamProperties Properties = _camera.Properties;
            PropPair range = Properties[CamProc.Brightness];
            double currentVal = _camera.GetBrightness();
            if (currentVal - 1 >= range.Min)
            {
                _camera.SetBrightness(currentVal - 1);
                labelBrightnessVal.Text = _camera.GetBrightness().ToString();
            }
        }

        private void buttonAddExposure_Click(object sender, EventArgs e)
        {
            CamProperties Properties = _camera.Properties;
            PropPair range = Properties[CamProc.Exposure];
            double currentVal = _camera.GetExposure();
            if (currentVal + 1 <= range.Max)
            {
                _camera.SetExposure(currentVal + 1);
                labelExposureVal.Text = _camera.GetExposure().ToString();
            }
        }

        private void buttonReduceExposure_Click(object sender, EventArgs e)
        {
            CamProperties Properties = _camera.Properties;
            PropPair range = Properties[CamProc.Exposure];
            double currentVal = _camera.GetExposure();
            if (currentVal - 1 >= range.Min)
            {
                _camera.SetExposure(currentVal - 1);
                labelExposureVal.Text = _camera.GetExposure().ToString();
            }
        }

        private void OnCameraPropertyUpdated(object sender, CamPropValUpdatedEventArgs e)
        {
            switch (e.ProType)
            {
                case CamProc.Brightness:
                    if(_option.EnableAdjustParams)
                    {
                        labelBrightnessVal.Text = e.Value.ToString();
                    }
                    break;
                case CamProc.Contrast:
                    break;
                case CamProc.Hue:
                    break;
                case CamProc.Saturation:
                    break;
                case CamProc.Sharpness:
                    break;
                case CamProc.Gamma:
                    break;
                case CamProc.WhiteBalance:
                    break;
                case CamProc.Backlight:
                    break;
                case CamProc.Gain:
                    break;
                case CamProc.Exposure:
                    if (_option.EnableAdjustParams)
                    {
                        labelExposureVal.Text = e.Value.ToString();
                    }
                    break;
                case CamProc.Focus:
                    break;
                default:
                    break;
            }
        }

        private void 启用系统默认参数SetAsDefaultSettingToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
    }
}
